package util;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;

/**
 * 通用签名小工具.
 *
 * @author lamb
 */
public final class SignUtil {

    /**
     * 字符集.
     */
    private static final Charset CHARSET_UTF8 = Charset.forName("UTF-8");

    /**
     * 算法.
     */
    private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";

    /**
     * 签名.
     *
     * @param content 内容.
     * @param key     key.
     * @return 签名.
     * @throws Exception 异常.
     */
    public static String hmacSha256(String content, String key) throws Exception {
        if (null == content || null == key || content.isEmpty() || key.isEmpty()) {
            throw new IllegalArgumentException("content or key not found");
        }
        Mac hmac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(CHARSET_UTF8), HMAC_SHA256_ALGORITHM);
        hmac.init(keySpec);
        byte[] array = hmac.doFinal(content.getBytes(CHARSET_UTF8));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1, 3);
        }
        return sb.toString().toLowerCase();
    }

    /**
     * 签名小工具.
     *
     * @param appId     应用id.
     * @param appSecret 应用密钥.
     * @param timestamp 时间.
     * @param body      内容.
     * @return 签名, appId.timestamp.signValue.
     * @throws Exception e.
     */
    public static String sign(String appId, String appSecret, long timestamp,
                              String path, String body) throws Exception {
        if (null == appId || null == appSecret || null == body || null == path) {
            throw new IllegalArgumentException("签名失败,签名参数有空值");
        }
        String auth = appId + "." + timestamp + ".";
        auth += hmacSha256(auth + path + body, appSecret);
        return auth;
    }
}

